package com.wq.proxy.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: wangqiang20995
 * @Date:2018/10/10
 * @Description:没有实现类的对象代理
 * @Resource:
 */
public class ProxyInterfaceHandler<T> implements InvocationHandler {

    private Class<T> proxyInterface;

    private String proxyClass;

    public ProxyInterfaceHandler(Class<T> proxyInterface) {
        this.proxyInterface = proxyInterface;
        this.proxyClass = proxyInterface.getName();
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("whether current proxy object or not --> " + proxyInterface.isInterface());
        System.out.println("proxy object class --> " + proxyClass);
        RpcProxy rpcProxy = new RpcProxy(method);
        Object response = rpcProxy.doRpc(args);
        if(response != null && response instanceof List){
            StringBuilder builder = new StringBuilder();
            List list = (List) response;
            for(Object obj : list){
                builder.append(obj).append("|");
            }
            builder.deleteCharAt(builder.length() - 1);
            return builder.toString();
        }
        return "empty response or illegal type";
    }


    class RpcProxy {
        private Method proxyMethod;

        public RpcProxy(Method method) {
            this.proxyMethod = method;
        }

        public Object doRpc(Object[] args) {
            try {
                List<String> list = new ArrayList<>(args.length);
                for (Object obj : args) {
                    list.add(obj.getClass().getName());
                }
                list.add(proxyMethod.getName());
                return list;
            } catch (Exception e) {
                System.out.println("exception happens while rpc calls");
                return null;
            }
        }
    }

    public static void main(String args[]) {
        Class clazz = CommonService.class;
        InvocationHandler handler = new ProxyInterfaceHandler<CommonService>(clazz);
        CommonService proxy = (CommonService) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, handler);
        System.out.println("proxy object class --> " + proxy.getClass().getName());
        System.out.println(proxy.postService(1));
    }
}
